package cn.topevery.garden.wapi.controller;

import cn.topevery.garden.wapi.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Slf4j
@RestController
@RequestMapping(value = "/rs/geo")
public class GeoServerController {

    private final static String[] hexArray = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    @Value("${geo.file.path}")
    public String fileRootPath;

    @GetMapping(value = "/requestGeo")
    public void requestGeo(String url, String layer, String zoom, HttpServletResponse response) throws NoSuchAlgorithmException, IOException {
        layer = layer.replace(":", "_");
        dirExists(fileRootPath + layer + "/" + zoom);
        //创建具有MD5算法的信息摘要
        MessageDigest md = MessageDigest.getInstance("MD5");
        //使用指定的字节数组对摘要进行最后更新，然后完成摘要计算
        byte[] bytes = md.digest(ObjectUtils.isNotEmpty(layer.indexOf("tian"))?url.getBytes():url.substring(url.indexOf("wms")).getBytes());
        //将得到的字节数组变成字符串返回
        String fileName = byteArrayToHex(bytes).toUpperCase() + ".png";
        fileExists(fileName, layer + "/" + zoom + "/", url, response);
    }

    private void fileExists(String fileName, String dir, String url, HttpServletResponse response) throws IOException {
        File imageFile = new File(fileRootPath + dir + fileName);
        if (!imageFile.exists()) {
            byte[] arr;
            arr = HttpUtils.doGeoRequestForFile(url);
            try {
                //创建输出流
                FileOutputStream fileOutputStream = new FileOutputStream(imageFile);
                if (arr != null) {
                    fileOutputStream.write(arr);
                }
                //关闭输出流
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        writeResponsePng(dir + fileName, response);
    }

    private void dirExists(String dirPath) {
        File directory = new File(dirPath);
        if (!directory.exists() && !directory.isDirectory()) {
            log.info(dirPath + "目录不存在,创建目录");
            directory.mkdirs();
        }
    }

    private void writeResponsePng(String fileName, HttpServletResponse response) throws IOException {
        response.setHeader("content-disposition", "inline;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.setContentType("image/png");
        FileInputStream in;
        OutputStream out;
        in = new FileInputStream(new File(fileRootPath + fileName));
        out = response.getOutputStream();
        byte[] b = new byte[1024];
        while ((in.read(b)) != -1) {
            out.write(b);
        }
        out.flush();
        in.close();
        out.close();
    }

    /**
     * 将字节数组转换成十六进制，并以字符串的形式返回
     * 128位是指二进制位。二进制太长，所以一般都改写成16进制，
     * 每一位16进制数可以代替4位二进制数，所以128位二进制数写成16进制就变成了128/4=32位。
     */
    private static String byteArrayToHex(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (byte value : b) {
            sb.append(byteToHex(value));
        }
        return sb.toString();
    }

    /**
     * 将一个字节转换成十六进制，并以字符串的形式返回
     */
    public static String byteToHex(byte b) {
        int n = b;
        if (n < 0) {
            n = n + 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexArray[d1] + hexArray[d2];
    }


}
